package cn.nawang.ebeim.api.service.impl;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import cn.nawang.ebeim.api.bean.IsOnLineBean;
import cn.nawang.ebeim.api.domain.HeartLog;
import cn.nawang.ebeim.api.domain.User;
import cn.nawang.ebeim.api.repository.HeartLogRepository;
import cn.nawang.ebeim.api.repository.impl.BackupLogQueryRepositoryImpl;
import cn.nawang.ebeim.api.repository.impl.CaQueryRepositoryImpl;
import cn.nawang.ebeim.api.repository.impl.DatasourceQueryRepositoryImpl;
import cn.nawang.ebeim.api.repository.impl.HeartLogRepositoryImpl;
import cn.nawang.ebeim.api.repository.impl.SpaceSizeCountImpl;
import cn.nawang.ebeim.api.service.HeartLogService;
import cn.nawang.ebeim.api.utils.Constant;
import cn.nawang.ebeim.api.utils.DateOperate;
import cn.nawang.ebeim.api.utils.DateUtils;
import cn.nawang.ebeim.api.utils.ValidateUtil;

/**
 * @ClassName: HeartLogServiceImpl
 * @Description: 心跳表的业务逻辑接口实现
 * @author fanyb
 * @date Aug 6, 2015 10:21:11 AM
 * @version v1.0
 */
@Service("heartLogService")
public class HeartLogServiceImpl implements HeartLogService {
  private static final Logger LOG = LoggerFactory.getLogger(HeartLogServiceImpl.class);

  @Autowired
  private HeartLogRepositoryImpl heartLogRepositoryImpl;

  @Autowired
  private HeartLogRepository heartLogRepository;

  @Autowired
  private SpaceSizeCountImpl spaceSizeCountImpl;

  @Autowired
  private BackupLogQueryRepositoryImpl backupLogQueryRepositoryImpl;

  @Autowired
  private DatasourceQueryRepositoryImpl datasourceQueryRepositoryImpl;

  @Autowired
  private CaQueryRepositoryImpl caQueryRepositoryImpl;


  /**
   * @author zhangjf
   * @Description: 保存
   * @param @param heartLog
   * @date 2015年10月28日上午10:34:48
   *
   * @修改人 张建峰
   * @修改日期
   */
  public void save(HeartLog heartLog) {
    heartLogRepository.save(heartLog);
  }

  /**
   * @author zhangjf
   * @Description: 根据用户id获取在线情况列表
   * @param @return
   * @date 2015年10月28日下午5:05:37
   *
   * @修改人 张建峰
   * @修改日期
   */
  public List<IsOnLineBean> getIsOnLineBeans(String userId) {
    List<String> macList = heartLogRepositoryImpl.findMacByUserId(userId);
    String terminalIds = "";
    for (String mac : macList) {
      terminalIds += "'" + mac + "',";
    }
    if (terminalIds.length() > 0) {
      terminalIds = terminalIds.substring(0, terminalIds.length() - 1);
    }
    List<HeartLog> list = heartLogRepositoryImpl.getListByTerminalIds(terminalIds);
    Long nowTime = new Date().getTime();
    List<IsOnLineBean> beans = new ArrayList<IsOnLineBean>();
    for (HeartLog heartLog : list) {
      IsOnLineBean bean = new IsOnLineBean();
      bean.setMac(heartLog.getTerminalId());
      long actTime = heartLog.getActTime();
      long compare = nowTime - actTime;
      int status = 1;
      if (compare > 1000 * 60 * 6) {// 现在时间减去最新插入的时间大于6分钟，则离线
        status = 0;
      }
      bean.setStatus(status);
      beans.add(bean);
    }
    return beans;
  }

  /**
   * 
   * @author: huanghj
   * @Description: 根据用户Id获取设备状态和设备名称
   * @param @param userId
   * @param @return
   * @return List
   * @date 2015年10月29日上午10:49:33
   *
   * @修改人
   * @修改日期
   */
  public List getIsOnLineBeansList(String userId, String onlineSel) {
    List<Map<String, Object>> list = heartLogRepositoryImpl.findTerminalByUser(userId);
    Long nowTime = new Date().getTime();
    List<IsOnLineBean> beans = new ArrayList<IsOnLineBean>();
    for (Map<String, Object> map : list) {
      IsOnLineBean bean = new IsOnLineBean();
      bean.setDeviceName(map.get("bind_device_name").toString());
      bean.setMac(map.get("terminal_id").toString());
      int status = 1;
      if (String.valueOf(map.get("act_time")) == null
         || String.valueOf(map.get("act_time")).equals("null")) {
        status = 0;
      } else {
        long actTime = Long.parseLong(String.valueOf(map.get("act_time")));
        long compare = nowTime - actTime;
        if (compare > 1000 * 60 * 6) {// 现在时间减去最新插入的时间大于6分钟，则离线
          status = 0;
        }
      }
      bean.setStatus(status);
      if (onlineSel.equals("1")) {
        if (status == 1) {
          beans.add(bean);
        }
      } else {
        beans.add(bean);
      }
    }
    return beans;
  }



  /**
   * 
   * @author fanyb
   * @Description: 判断终端在线情况
   * @param terminalId 终端id
   * @return String
   * @date Aug 6, 20152:56:02 PM
   *
   * @修改人
   * @修改日期
   */
  public String getIsOnline(String terminalId) {
    LOG.debug("getIsOnline");
    Date date = new Date();
    // level=3的统计
    int levelCount = 0;
    // 当前时间的时间戳值
    long currTime = date.getTime();
    // 半个小时以前的时间戳值
    long halfHourAgo = DateUtils.getDateTimeMinuteAfter(-30).getTime();
    List list = heartLogRepositoryImpl.findHalfHourList(currTime, halfHourAgo, terminalId);
    // 如果记录不满六条就说明是离线
    if (list.size() < 6) {
      return "离线";
    } else {
      for (int i = 0; i < list.size(); i++) {
        Object[] obj = (Object[]) list.get(i);
        // 如果level=3则，levelCount加1
        if (obj[3] == "3") {
          levelCount++;
        }
      }
      // 如果levelcount等于6,则是离线
      if (levelCount == 6) {
        return "离线";
      } else {
        return "在线";
      }
    }
  }

  /**
   * 
   * @author fanyb
   * @Description: 获取到该终端最后一次在线的时间
   * @param terminalId 终端编号
   * @return String 该终端最后一次在线的时间
   * @date Aug 7, 201511:12:08 AM
   *
   * @修改人
   * @修改日期
   */
  public String getLastOnlineTime(String terminalId) {
    LOG.debug("getLastOnlineTime");
    List heartLogList = heartLogRepository.getLastOnlineTime(terminalId);
    // 如果heartLog为空的话，则没有最后一次在线时间
    if (heartLogList == null || heartLogList.size() < 1) {
      return "";
    }
    HeartLog heartLog = (HeartLog) heartLogList.get(0);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:hh:ss");
    String sd = sdf.format(new Date(Long.parseLong(heartLog.getActTime().toString())));
    return sd;
  }

  /**
   * 
   * @author fanyb
   * @Description: 获取该终端某个时间段在线时长（小时）
   * @param startTime 起始时间戳
   * @param endTime 结束时间戳
   * @param terminalId 终端编号
   * @return double 该终端当天在线时长
   * @date Aug 6, 20153:44:52 PM
   *
   * @修改人
   * @修改日期
   */
  public double getTodayOnlineHour(long startTime, long endTime, String terminalId) {
    LOG.debug("getTodayOnlineHour");
    // 正常情况
    String level = Constant.HEART_LOG_LEVEL_ONE;
    // 总共时长（小时）
    double totalHour = 0.0;
    int count = heartLogRepositoryImpl.getHeartLogCount(startTime, endTime, terminalId, level);
    // 该终端编号在线
    int totalMinute = count * 3;
    totalHour = totalMinute / 60.0;
    return totalHour;
  }

  /**
   * 
   * @author fanyb
   * @Description:获取该终端当天的离线比
   * @param terminalId 终端编号
   * @return double 该终端当天的离线比
   * @date Aug 6, 20154:06:42 PM
   *
   * @修改人
   * @修改日期
   */
  public double getTodayOfflinePerson(String terminalId) {
    LOG.debug("getTodayOfflinePerson");
    Date date = new Date();
    // 当前时间戳
    long currTime = date.getTime();
    // 今天开始的时间戳
    long startTime = DateUtils.getTodayStartTime(0);
    // 当天结束时间戳
    long endTime = DateUtils.getTodayEndTime(0);
    // 计算当天0点的时间到当前的时间差(小时)
    double timeDifference = (currTime - startTime) / (1000 * 3600.0);
    double totalHour = getTodayOnlineHour(startTime, endTime, terminalId);
    if (timeDifference != 0) {
      return (timeDifference - totalHour) / timeDifference;
    } else {
      return 1;
    }
  }

  @Override
  public List<Map<String, Object>> getMemoryCase(User user) {
    LOG.debug("getMemoryCase");
    List<Map> usageList = spaceSizeCountImpl.getUsageSpaceSizeByTerminalId(user);// 获取每个数据源已使用的空间大小
    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    double userSpace = Double.valueOf(user.getSpaceSize());
    if (usageList != null && !usageList.isEmpty()) {
      for (int j = 0; j < usageList.size(); j++) {
        // [CA-00000001, TM-1438826840942-976, 1]
        // usageList
        Map<String, Object> memoryCaseMap = new HashMap<String, Object>();
        DecimalFormat df = new DecimalFormat("0.00");
        double spaceUsaged =
            Double.valueOf(usageList.get(j).get("space_usage").toString()) / 1024 / 1024 / 1024;
        memoryCaseMap.put("id", usageList.get(j).get("id"));// 数据源id
        memoryCaseMap.put("name", usageList.get(j).get("name"));// 数据源名称
        memoryCaseMap.put("usedSpaceSize", df.format(spaceUsaged));// 已用
        Double canUse = userSpace - spaceUsaged;
        memoryCaseMap.put("availableSpaceSize", df.format(canUse));// 可用
        memoryCaseMap.put("totalAccounting", df.format(spaceUsaged / userSpace));// 占比
        list.add(memoryCaseMap);
      }
    }
    return list;
  }

  @Scheduled(cron = "0 0 4 * * ? ") // 每5秒执行一次
  @Override
  public void deleteFiveDayAgo() {
    LOG.debug("deleteFiveDayAgo");
    long fiveDayStart = DateUtils.getTodayStartTime(2);
    heartLogRepositoryImpl.deleteByActTimeAgo(fiveDayStart);
  }

  @Override
  public boolean paramCheck(String lic) {
    if (ValidateUtil.isEmpty(lic)) {
      return false;
    }
    return true;
  }

  @Override
  public Map<String, Double> findTotalMemoryCase(User user) {
    double usageSize = spaceSizeCountImpl.getUsageSpaceSizeByCustomer(user);// 已使用存储大小
    double countSize = Double.valueOf(user.getSpaceSize()); // 存储空间总大小
    usageSize = usageSize / 1024 / 1024 / 1024;
    double availableSpaceSize = Double.valueOf(user.getSpaceSize()) - usageSize;// 可用空间大小
    double availableSpacePercent = availableSpaceSize / countSize * 1.0;// 可用空间百分比
    double usedSpacePercent = usageSize / countSize * 1.0;// 已用空间百分比
    if (countSize == 0) {
      availableSpacePercent = 0.0;
      usedSpacePercent = 0.0;
    }
    Map<String, Double> map = new HashMap<String, Double>();
    map.put("availableSpaceSize", availableSpacePercent);
    map.put("usedSpacePercent", usedSpacePercent);
    return map;
  }

  /**
   * @author 张建峰
   * @Description: TODO
   * @param @param customerId
   * @param @return
   * @date 2015年10月16日下午3:40:56
   *
   * @修改人 张建峰
   * @修改日期
   */
  @Override
  public Map<String, Double> getMemoryCaseNoPercent(User user) {
    double usageSize = spaceSizeCountImpl.getUsageSpaceSizeByCustomer(user);// 已使用存储大小
    double countSize = Double.valueOf(user.getSpaceSize()); // 存储空间总大小
    usageSize = usageSize / 1024 / 1024 / 1024;
    double availableSpaceSize = Double.valueOf(user.getSpaceSize()) - usageSize;// 可用空间大小
    Map<String, Double> map = new HashMap<String, Double>();
    map.put("countSize", countSize);
    map.put("availableSpaceSize", availableSpaceSize);
    return map;
  }

  @Override
  public Map<String, Integer> getMemoryAll(User user) {
    long usageSize = spaceSizeCountImpl.getUsageSpaceSizeByUser(user.getId());// 已使用存储大小
    int countSize = 0;
    if (user.getSpaceSize() != null) {
      countSize = Integer.valueOf(user.getSpaceSize()); // 存储空间总大小
    }
    int usedSize = (int) Math.round(usageSize / (1024.0 * 1024 * 1024));
    int availableSpaceSize = countSize - usedSize;// 可用空间大小
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("countSize", countSize);
    map.put("availableSpaceSize", availableSpaceSize);
    map.put("usageSize", usedSize);
    return map;
  }



  @Override
  public Map<String, String> getBackupTimes(String userId) {
    int today_count = backupLogQueryRepositoryImpl.getTodayBackupTimes(userId);
    int all_conut = datasourceQueryRepositoryImpl.getBackupCountByUser(userId);
    Map<String, String> map = new HashMap<String, String>();
    map.put("todayCount", String.valueOf(today_count));
    map.put("allCount", String.valueOf(all_conut));
    return map;
  }

  @Override
  public Map<String, String> getServerTimes(String labId) {
    // 获得剩余时间
    long endTime = caQueryRepositoryImpl.getUserCaEndTime(labId);
    long days = DateOperate.getLateTime(endTime);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    String date = sdf.format(new Date(endTime));
    Map<String, String> map = new HashMap<String, String>();
    map.put("endTime", date);
    map.put("days", String.valueOf(days));
    return map;
  }

  @Override
  public List<IsOnLineBean> getIsOnLineBeansList(String userId, String terminalId,
      String deviceName) {
    List<IsOnLineBean> beans = new ArrayList<IsOnLineBean>();
    IsOnLineBean bean = new IsOnLineBean();
    bean.setDeviceName(deviceName);
    bean.setMac(terminalId);
    beans.add(bean);
    List<Map<String, Object>> list = heartLogRepositoryImpl.findTerminalByUser(userId);
    Long nowTime = new Date().getTime();
    for (Map<String, Object> map : list) {
      if (!map.get("terminal_id").toString().equals(terminalId)) {
        bean.setDeviceName(map.get("bind_device_name").toString());
        bean.setMac(map.get("terminal_id").toString());
        long actTime = Long.parseLong(String.valueOf(map.get("act_time")));
        long compare = nowTime - actTime;
        int status = 1;
        if (compare > 1000 * 60 * 6) {// 现在时间减去最新插入的时间大于6分钟，则离线
          status = 0;
        }
        bean.setStatus(status);
        beans.add(bean);
      }
    }
    return beans;
  }



}
